#ifndef TCPSession_h__
#define TCPSession_h__
#include <boost/asio.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/array.hpp>
#include <list>
#include "IObject/StdCmm.h"


class  IPacketCodec;
class  SessionManager;
struct SendBuffer;
struct RawPacket;
class ILogger;

class TCPSession : public boost::enable_shared_from_this<TCPSession>, 
				   public boost::noncopyable
{
	friend class SessionManager;

public:
	TCPSession(boost::shared_ptr<boost::asio::ip::tcp::socket> pSocket,
		SessionManager & sm, SocketID socketID, SessionType type);

	virtual ~TCPSession();

public:
	SendResult AsyncSend(const char *pBuffer, int size, CONTENT_TYPE type);
	SendResult SyncSend(const char *pBuffer, int size, CONTENT_TYPE type);

	void Close();
	bool IsAlive();

	void Start();
	SessionType	GetSessionType() const;

	boost::shared_ptr<boost::asio::ip::tcp::socket> Socket();

	time_t GetLastRecvTime();

protected:
	void RealClose();
	void PacketCompleteCallback(RawPacket* pPacket);
	
	void DoAsyncSend();

	void OnAsyncSendComplete(const boost::system::error_code & e,
		size_t bytes_transferd);

	void Read();

	void OnAsyncRead(const boost::system::error_code & e,
		size_t bytes_transferd);

protected:
	boost::shared_ptr<boost::asio::ip::tcp::socket> m_pSocket;
	SessionManager & m_SessionManager;
	SocketID m_SocketID;
	bool	 m_bClosed;

	IPacketCodec* m_pPacketCodec;

	boost::mutex		   m_lock;
	std::list<SendBuffer*> m_SendBufferList;
	uint32_t			   m_BatchSendCount;

	boost::array<char,8192>	m_RecvBuffer;
	std::string				m_RecvCache;
	SessionType				m_SessionType;

	time_t					m_LastRecv;
	ILogger					*m_pLogger;
};
#endif // TCPSession_h__
